package net.bat.web.api;

import java.util.Date;
import java.util.List;
import java.util.Map;

import net.bat.advice.LogAspect;
import net.bat.dao.UserDAO;
import net.bat.dao.UserDAO.Action;
import net.bat.dto.LoginInfo;
import net.bat.dto.ResultDTO;
import net.bat.entity.EDlr;
import net.bat.entity.IdEntity;
import net.bat.entity.Message;
import net.bat.entity.Task;
import net.bat.entity.User;
import net.bat.repository.TaskDao;
import net.bat.repository.UserDao;
import net.bat.rest.RestService;
import net.bat.service.account.AccountService;
import net.bat.service.account.ShiroDbRealm.ShiroUser;
import net.bat.service.dlr.DlrService;
import net.bat.service.message.MessageService;
import net.bat.service.task.TaskService;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ApiController {
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserDAO dao;
	@Autowired
	private TaskDao taskDao;
	@Autowired
	private TaskService taskService;
	@Autowired
	private DlrService dlrService;
	@Autowired
	private MessageService messageService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private RestService restService;
	
	public static final String ROLE_ADMIN_JG= "admin_jg";
	public static final String ROLE_ADMIN_XH= "admin_xh";
	public static final String ROLE_ADMIN= "admin";

	/*---------------for User---------------------**/
	@RequestMapping(value = "/rest/User", method = RequestMethod.POST)
	@ResponseBody
	public User updateUser(@RequestBody Map<String, Object> rmap) throws Exception {
		User user = dao.load(User.class, rmap);
		if (user.getRegisterDate() == null) {
			user.setRegisterDate(new Date());
		}
		// 如果需要修改密码
		if (rmap.containsKey("plainPassword")) {
			accountService.entryptPassword(user);
		}
		dao.save(user);
		return user;
	}

	@RequestMapping(value = "/rest/User/{id}", method = RequestMethod.PUT)
	@ResponseBody
	public User updateUser(@PathVariable Long id, @RequestBody Map<String, Object> rmap) throws Exception {
		User user = dao.load(User.class, rmap);
		// 如果需要修改密码
		if (rmap.containsKey("plainPassword")) {
			accountService.entryptPassword(user);
		}
		dao.save(user);
		return user;
	}

	@RequestMapping(value = "/rest/User", method = RequestMethod.DELETE)
	@ResponseBody
	public <T> void removeUser(@RequestBody Map<String, Object> rmap) throws Exception {
		List ids = (List) rmap.get("ids");
		for (int i = 0; i < ids.size(); i++) {
			Long id = Long.parseLong(ids.get(i).toString());
			LogAspect.logOper("User", id, null, Action.REMOVE);
			accountService.deleteUser(id);
		}
	}

	/*---------------for Task---------------------**/
	// extjs调用rec.save时 add or update 都有可能
	@RequestMapping(value = "/rest/Task", method = RequestMethod.POST)
	@ResponseBody
	public <T> T updateTask(@RequestBody Map<String, Object> rmap) throws Exception {
		User user = new User(getCurrentUserId());
		rmap.put("user", user);
		return (T) restService.updateEntity("Task", rmap);
	}

	@RequestMapping(value = "/list/Task", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getTasks(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		Page<Task> p = taskService.getTaskEntities(page, start, limit, filter, sort, getCurrentUserId());
		ResultDTO r = new ResultDTO();
		r.total = p.getTotalElements();
		r.data = p.getContent();
		return r;
	}

	/*
	 * // 代理机构管理员获取本机构下代理人列表
	 * 
	 * @RequestMapping(value = "/list/EDlr", method = RequestMethod.GET)
	 * 
	 * @ResponseBody
	 * public ResultDTO getDlrs(@RequestParam(value = "page", required = false) Integer page,
	 * 
	 * @RequestParam(value = "start", required = false) Integer start,
	 * 
	 * @RequestParam(value = "limit", required = false) Integer limit,
	 * 
	 * @RequestParam(value = "filter", required = false) String filter,
	 * 
	 * @RequestParam(value = "sort", required = false) String sort) throws Exception {
	 * long uid = getCurrentUserId();
	 * User usr = dao.find(User.class, uid);
	 * if (usr.getSsjg() > 0) {
	 * // 界面无检索
	 * if (filter == null) {
	 * filter = "[{\"operator\":\"eq\",\"value\":" + usr.getSsjg() + ",\"property\":\"pid\"}]";
	 * } else {
	 * // 界面已有检索
	 * filter = "[{\"operator\":\"eq\",\"value\":" + usr.getSsjg() + ",\"property\":\"pid\"},"
	 * + filter.substring(1);
	 * }
	 * }
	 * return restService.getEntities(page, start, limit, filter, sort, "EDlr");
	 * }
	 */

	@RequestMapping(value = "/list/EDlr", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getEdlrs(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		User user = getCurrentUser();
		ResultDTO r = new ResultDTO();
		if (user.getRoles().equals(ROLE_ADMIN_JG) && (user.getSsjg() != 0)) {
			if (filter == null) {
				 filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"pid\"}]";
				 } else {
				 // 界面已有检索
				 filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"pid\"},"
				 + filter.substring(1);
				 }
		} 
		

		return restService.getEntities(page, start, limit, filter, sort, "EDlr");
	}
	
	/**
	 * 填报代理人
	 * @param page
	 * @param start
	 * @param limit
	 * @param filter
	 * @param sort
	 * @return
	 * @throws Exception
	 * @author wangshuxin
	 * 2016-4-18
	 */
	@RequestMapping(value = "/list/EDlrSh", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getEdlrShs(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		User user = getCurrentUser();
		ResultDTO r = new ResultDTO();
		if (user.getRoles().equals(ROLE_ADMIN_JG) && (user.getSsjg() != 0)) {
			// 界面无检索
			  if (filter == null) {
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"pid\"}]";
			  } else {
			  // 界面已有检索
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"pid\"},"
			  + filter.substring(1);
			  }
		}
		//add by wsx 20160426
		else if(user.getRoles().equals(ROLE_ADMIN_XH)){
			// 界面无检索
			  if (filter == null) {
			  filter = "[{\"operator\":\"eq\",\"value\":2,\"property\":\"shzt\"}]";
			  }
		}
		//end
		return  restService.getEntities(page, start, limit, filter, sort, "EDlrSh");
	}
	
	@RequestMapping(value = "/list/EDljg", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getEDljgs(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		User user = getCurrentUser();
		ResultDTO r = new ResultDTO();
		if (user.getRoles().equals(ROLE_ADMIN_JG) && (user.getSsjg() != 0)) {
			// 界面无检索
			  if (filter == null) {
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"id\"}]";
			  } else {
			  // 界面已有检索
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"id\"},"
			  + filter.substring(1);
			  }
		}
		return  restService.getEntities(page, start, limit, filter, sort, "EDljg");
	}
	
	@RequestMapping(value = "/list/EDljgSh", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getEDljgShs(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		User user = getCurrentUser();
		ResultDTO r = new ResultDTO();
		if (user.getRoles().equals(ROLE_ADMIN_JG) && (user.getSsjg() != 0)) {
			// 界面无检索
			  if (filter == null) {
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"id\"}]";
			  } else {
			  // 界面已有检索
			  filter = "[{\"operator\":\"eq\",\"value\":" + user.getSsjg() + ",\"property\":\"id\"},"
			  + filter.substring(1);
			  }
		}
		//add by wsx 20160426
		else if(user.getRoles().equals(ROLE_ADMIN_XH)){
			// 界面无检索
			  if (filter == null) {
			  filter = "[{\"operator\":\"eq\",\"value\":2,\"property\":\"shzt\"}]";
			  }
		}
		//end
		return  restService.getEntities(page, start, limit, filter, sort, "EDljgSh");
	}
	
	

	@RequestMapping(value = "/list/Message", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getMessages(@RequestParam(value = "page", required = true) int page,
			@RequestParam(value = "start", required = true) int start,
			@RequestParam(value = "limit", required = true) int limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		User user = getCurrentUser();
		ResultDTO r = new ResultDTO();
		Page<Message> p;
		if (user.getRoles().equals(ROLE_ADMIN_JG) && (user.getSsjg() != 0)) {
			p = messageService.getMessageEntities(page, start, limit, filter, sort, user.getSsjg());

		} else {
			// r=restService.getEntities(page, start, limit, filter, sort, "Message");
			p = messageService.getMessageEntities(page, start, limit, filter, sort, 0);
		}
		r.total = p.getTotalElements();
		r.data = p.getContent();
		return r;
	}

	/*---------------for command rest---------------------**/

	@SuppressWarnings({ "unchecked" })
	@RequiresPermissions("*:view")
	@RequestMapping(value = "/exists/{entity}", method = RequestMethod.GET)
	@ResponseBody
	public boolean exists(@PathVariable String entity, @RequestParam(value = "pn", required = true) String pn,
			@RequestParam(value = "pv", required = true) Object pv) throws Exception {
		return restService.exists(entity, pn, pv);
	}

	@RequiresPermissions("*:view")
	@RequestMapping(value = "/ls/{entity}/{property}", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO listEntities(@PathVariable String entity, @PathVariable String property,
			@RequestParam(value = "limit", required = false) int limit,
			@RequestParam(value = "kw", required = false) String kw) throws Exception {
		return restService.listEntities(entity, property, kw, limit);
	}

	@SuppressWarnings({ "unchecked" })
	@RequiresPermissions("*:view")
	@RequestMapping(value = "/distinct/{entity}/{property}", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO<Object> distinct(@PathVariable String entity, @PathVariable String property,
			@RequestParam(value = "limit", required = false) int limit,
			@RequestParam(value = "kw", required = false) String kw,
			@RequestParam(value = "filter", required = false) String filter) throws Exception {
		return restService.disticnt(entity, property, kw, limit, filter);
	}

	@RequestMapping(value = "/auth", method = RequestMethod.POST)
	@ResponseBody
	public User authenticate(@RequestBody LoginInfo request) {
		User user=accountService.login(request);
				if(request.pwdnew!=null){
					user.setPlainPassword(request.pwdnew);
					accountService.entryptPassword(user);
					dao.save(user);
				}
		return user;
	}

	@RequestMapping(value = "/list/{entity}", method = RequestMethod.GET)
	@ResponseBody
	public ResultDTO getEntities(@PathVariable String entity,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "start", required = false) Integer start,
			@RequestParam(value = "limit", required = false) Integer limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		return restService.getEntities(page, start, limit, filter, sort, entity);
	}

	@RequestMapping(value = "/rest/{entity}", method = RequestMethod.GET)
	@ResponseBody
	public <T extends IdEntity> List<T> geEntityList(@PathVariable String entity,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "start", required = false) Integer start,
			@RequestParam(value = "limit", required = false) Integer limit,
			@RequestParam(value = "filter", required = false) String filter,
			@RequestParam(value = "sort", required = false) String sort) throws Exception {
		if ((sort == null) && entity.equals("Attach")) {
			sort = "[{\"property\":\"ord\",\"direction\":\"ASC\"}]";
		}
		return restService.getEntityList(page, start, limit, filter, sort, entity);
	}

	@RequestMapping(value = "/rest/{entity}/{id}", method = RequestMethod.GET)
	@ResponseBody
	public <T> T getEntity(@PathVariable String entity, @PathVariable Long id) throws Exception {
		return (T) restService.getEntity(entity, id);
	}

	@RequestMapping(value = "/rest/{entity}/{id}", method = RequestMethod.PUT)
	@ResponseBody
	public <T> T updateEntity(@PathVariable String entity, @PathVariable Long id, @RequestBody Map<String, Object> rmap)
			throws Exception {
		return (T) restService.updateEntity(entity, id, rmap);
	}

	@RequestMapping(value = "/rest/{entity}", method = RequestMethod.POST)
	@ResponseBody
	public <T> T updateEntity(@PathVariable String entity, @RequestBody Map<String, Object> rmap) throws Exception {
		return (T) restService.updateEntity(entity, rmap);
	}

	@RequestMapping(value = "/rest/{entity}", method = RequestMethod.DELETE)
	@ResponseBody
	public <T> T removeEntity(@PathVariable String entity, @RequestBody Map<String, Object> rmap) throws Exception {
		List ids = (List) rmap.get("ids");
		return (T) restService.removeEntitys(entity, ids.toArray());
	}

	private String addFilter(String filter, String filter_add) {
		if (filter == null) {
			return "[" + filter_add + "]";
		} else {
			return "[" + filter_add + "," + filter.substring(1) + "]";
		}
	}

	private Long getCurrentUserId() {
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		return user.id;
	}

	private User getCurrentUser() {

		ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();

		User user = userDao.findByLoginName(shiroUser.loginName);
		return user;
	}

}
